package com.zrc.japktool.ui.view;

import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import java.util.EnumSet;
import java.util.Random;

/**
 * 基于 WebLogView 的日志 UI 容器：包含控制栏（按钮+复选框）和 WebLogView 日志显示区域
 * 功能：支持 DEBUG/INFO/WARN/ERROR 分级日志发送、实时级别过滤、日志清空、自动滚动
 */
class Test5 {
    // 核心日志控件：替换原 LogTextField2 为 WebLogView
    private WebLogView webLogView;
    // 存储当前启用的日志级别（用于过滤逻辑）
    private EnumSet<WebLogView.LogLevel> enabledLevels;
    // 随机数生成器，用于批量测试
    private Random random = new Random();

    /**
     * 创建完整的日志 UI 布局（控制栏+日志区域）
     * @return 组装好的 BorderPane 主布局
     */
    public BorderPane createWebLogUI() {
        // 1. 初始化 WebLogView 核心控件
        initWebLogView();

        // 2. 创建控制栏（日志发送按钮 + 级别过滤复选框）
        HBox controlBar = createControlBar();

        // 3. 组装主布局（顶部控制栏，中间日志区域）
        BorderPane root = new BorderPane();
        root.setTop(controlBar);          // 顶部：功能控制栏
        root.setCenter(webLogView);       // 中间：Web 日志显示区域
        root.setPadding(new Insets(10));  // 整体内边距，避免控件贴边

        // 4. 添加批量日志测试按钮
        addBatchTestButton(controlBar);

        return root;
    }

    /**
     * 初始化 WebLogView：设置初始配置 + 打印启动欢迎日志
     */
    private void initWebLogView() {
        webLogView = new WebLogView();
        // 初始启用所有日志级别（DEBUG/INFO/WARN/ERROR）
        enabledLevels = EnumSet.allOf(WebLogView.LogLevel.class);

        // 程序启动时打印初始化日志（WebLogView 自带时间戳+颜色）
        webLogView.info("=== WebLogView 日志控件初始化完成 ===");
        webLogView.info("支持特性：1. 分级日志着色 2. 实时级别过滤 3. 自动滚动 4. 一键清空");
        webLogView.debug("调试信息：当前启用所有日志级别，可通过复选框切换过滤规则");
    }

    /**
     * 创建控制栏：包含 5 个功能按钮 + 4 个级别过滤复选框
     * @return 水平布局的控制栏
     */
    private HBox createControlBar() {
        // 水平布局：控件间距 15px，浅灰色背景（区分日志区域）
        HBox controlBar = new HBox(15);
        controlBar.setPadding(new Insets(10));
        controlBar.setStyle("-fx-background-color: #f0f0f0;");

        // ---------------------- 1. 日志发送按钮组 ----------------------
        Button btnDebug = new Button("发送DEBUG日志");
        Button btnInfo = new Button("发送INFO日志");
        Button btnWarn = new Button("发送WARN日志");
        Button btnError = new Button("发送ERROR日志");
        Button btnClear = new Button("清空日志");

        // 按钮点击事件：发送对应级别日志（含场景化测试内容）
        btnDebug.setOnAction(e -> sendFilteredLog(WebLogView.LogLevel.DEBUG,
                "DEBUG日志：用户操作追踪 | 测试长文本自动换行--------------------------------------------------------------------------------------------------------------------------------------（长文本末尾）"
        ));
        btnInfo.setOnAction(e -> sendFilteredLog(WebLogView.LogLevel.INFO,
                "INFO日志：系统状态通知 | 数据库连接成功（URL: jdbc:mysql://localhost:3306/test）| 加载配置文件: ./conf/app.properties"
        ));
        btnWarn.setOnAction(e -> sendFilteredLog(WebLogView.LogLevel.WARN,
                "WARN日志：非致命警告 | 本地缓存已过期（剩余空间: 12%）| 建议清理缓存目录: ./cache"
        ));
        btnError.setOnAction(e -> sendFilteredLog(WebLogView.LogLevel.ERROR,
                "ERROR日志：致命错误 | 文件写入失败（路径: ./log/app.log）| 原因：权限拒绝（当前用户无写权限）"
        ));
        btnClear.setOnAction(e -> {
            // 清空日志 + 打印清空时间（用 SimpleDateFormat 格式化时间）
            webLogView.clear();
            String clearTime = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date());
            webLogView.info("日志已清空（清空时间：" + clearTime + "）");
        });

        // ---------------------- 2. 日志级别过滤复选框组 ----------------------
        CheckBox cbDebug = new CheckBox("显示DEBUG");
        CheckBox cbInfo = new CheckBox("显示INFO");
        CheckBox cbWarn = new CheckBox("显示WARN");
        CheckBox cbError = new CheckBox("显示ERROR");

        // 初始状态：全选（显示所有级别日志）
        cbDebug.setSelected(true);
        cbInfo.setSelected(true);
        cbWarn.setSelected(true);
        cbError.setSelected(true);

        // 复选框变更事件：实时更新过滤级别（联动日志显示）
        cbDebug.selectedProperty().addListener((obs, oldVal, newVal) ->
                updateFilterLevels(cbDebug, cbInfo, cbWarn, cbError)
        );
        cbInfo.selectedProperty().addListener((obs, oldVal, newVal) ->
                updateFilterLevels(cbDebug, cbInfo, cbWarn, cbError)
        );
        cbWarn.selectedProperty().addListener((obs, oldVal, newVal) ->
                updateFilterLevels(cbDebug, cbInfo, cbWarn, cbError)
        );
        cbError.selectedProperty().addListener((obs, oldVal, newVal) ->
                updateFilterLevels(cbDebug, cbInfo, cbWarn, cbError)
        );

        // ---------------------- 3. 组装控制栏控件 ----------------------
        controlBar.getChildren().addAll(
                btnDebug, btnInfo, btnWarn, btnError, btnClear,  // 功能按钮组
                cbDebug, cbInfo, cbWarn, cbError                 // 过滤复选框组
        );
        return controlBar;
    }

    /**
     * 添加批量日志测试按钮
     */
    private void addBatchTestButton(HBox controlBar) {
        Button btnBatchTest = new Button("测试10000条日志");
        btnBatchTest.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white;");

        btnBatchTest.setOnAction(e -> {
            // 清空现有日志
            webLogView.clear();
            webLogView.info("开始批量添加10000条日志...");

            // 在新线程中生成日志，避免阻塞UI
            new Thread(() -> {
                long startTime = System.currentTimeMillis();

                // 生成10000条随机日志
                for (int i = 0; i < 10000; i++) {
                    final int index = i;
                    // 随机选择日志级别
                    WebLogView.LogLevel level = getRandomLogLevel();

                    // 构建日志消息
                    String message = String.format(
                            "批量测试日志 #%d | 这是一条%s级别的日志 | 测试内容：%s",
                            index,
                            level.name().toLowerCase(),
                            generateRandomContent()
                    );

                    // 在JavaFX主线程中添加日志
                    final WebLogView.LogLevel finalLevel = level;
                    final String finalMessage = message;
                    Platform.runLater(() -> sendFilteredLog(finalLevel, finalMessage));

                    // 每添加1000条日志，短暂休眠避免UI过载
                    if (index % 1000 == 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException ex) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                }

                // 计算并显示总耗时
                long endTime = System.currentTimeMillis();
                long duration = endTime - startTime;
                Platform.runLater(() -> {
                    webLogView.info(String.format(
                            "10000条日志添加完成 | 耗时：%d ms | 平均每条：%.2f ms",
                            duration,
                            (double) duration / 10000
                    ));
                    //webLogView.forceScrollToBottom();
                });
            }).start();
        });

        controlBar.getChildren().add(0, btnBatchTest); // 添加到最前面
    }

    /**
     * 随机获取日志级别
     */
    private WebLogView.LogLevel getRandomLogLevel() {
        WebLogView.LogLevel[] levels = WebLogView.LogLevel.values();
        return levels[random.nextInt(levels.length)];
    }

    /**
     * 生成随机日志内容
     */
    private String generateRandomContent() {
        String[] samples = {
                "系统正常运行中",
                "用户登录验证成功",
                "数据同步完成",
                "缓存更新操作",
                "网络连接状态检查",
                "配置参数加载",
                "定时任务执行",
                "数据库查询操作",
                "文件读写操作",
                "线程池状态监控"
        };

        // 随机选择一个样本内容，可能添加随机长度的后缀
        StringBuilder content = new StringBuilder(samples[random.nextInt(samples.length)]);
        if (random.nextBoolean()) {
            int suffixLength = random.nextInt(50) + 10;
            content.append(" | 附加信息：");
            for (int i = 0; i < suffixLength; i++) {
                content.append((char) ('a' + random.nextInt(26)));
            }
        }
        return content.toString();
    }

    /**
     * 根据复选框状态更新日志过滤级别（核心过滤逻辑）
     * @param cbDebug DEBUG级别复选框
     * @param cbInfo INFO级别复选框
     * @param cbWarn WARN级别复选框
     * @param cbError ERROR级别复选框
     */
    private void updateFilterLevels(CheckBox cbDebug, CheckBox cbInfo, CheckBox cbWarn, CheckBox cbError) {
        // 重置过滤级别集合
        enabledLevels.clear();

        // 根据复选框选中状态添加对应级别
        if (cbDebug.isSelected()) enabledLevels.add(WebLogView.LogLevel.DEBUG);
        if (cbInfo.isSelected()) enabledLevels.add(WebLogView.LogLevel.INFO);
        if (cbWarn.isSelected()) enabledLevels.add(WebLogView.LogLevel.WARN);
        if (cbError.isSelected()) enabledLevels.add(WebLogView.LogLevel.ERROR);

        // 边界处理：若未选中任何级别，默认启用「INFO+WARN+ERROR」（避免日志区域空白）
        if (enabledLevels.isEmpty()) {
            enabledLevels.addAll(EnumSet.of(
                    WebLogView.LogLevel.INFO,
                    WebLogView.LogLevel.WARN,
                    WebLogView.LogLevel.ERROR
            ));
            // 同步勾选复选框（避免用户操作与实际过滤规则不一致）
            cbInfo.setSelected(true);
            cbWarn.setSelected(true);
            cbError.setSelected(true);
            // 打印过滤规则变更日志
            webLogView.warn("过滤规则调整：未选中任何级别，默认启用 INFO/WARN/ERROR");
        }
    }

    /**
     * 发送过滤后的日志（仅发送当前启用级别的日志）
     * @param level 日志级别
     * @param message 日志内容
     */
    private void sendFilteredLog(WebLogView.LogLevel level, String message) {
        // 仅当该级别在启用列表中时，才发送日志
        if (enabledLevels.contains(level)) {
            switch (level) {
                case DEBUG -> webLogView.debug(message);
                case INFO -> webLogView.info(message);
                case WARN -> webLogView.warn(message);
                case ERROR -> webLogView.error(message);
            }
        }
    }

    // ---------------------- 对外提供的调用方法（可选）----------------------
    /**
     * 获取当前日志控件实例（供外部调用，如手动添加日志）
     * @return WebLogView 实例
     */
    public WebLogView getWebLogView() {
        return webLogView;
    }

    /**
     * 手动添加指定级别的日志（外部调用入口）
     * @param level 日志级别
     * @param message 日志内容
     */
    public void addExternalLog(WebLogView.LogLevel level, String message) {
        sendFilteredLog(level, message);
    }
}
